package at.jku.se.fastsell.rest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;

import com.owlike.genson.GenericType;
import com.owlike.genson.Genson;

import at.jku.se.fastsell.data.Auction;
import at.jku.se.fastsell.data.User;

public class RestAccess {

	private final static String SERVER_ADRESS = "http://10.0.3.2:8080/";

	// ----------------------------------------------------------------------------------

	private static HttpResponse executeHTTP(HttpUriRequest request) throws ServiceException {
		try {
			HttpClient client = new DefaultHttpClient();
			return client.execute(request);
		} catch (Exception e) {
			throw new ServiceException("Error in executing HTTP request", e);
		}
	}

	private static String convertEntityToJSON(HttpResponse response) throws IllegalStateException, IOException {
		String output, json = "";

		BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent())));

		while ((output = br.readLine()) != null) {
			json = json + output;
		}
		return json;
	}

	// ----------------------------------------------------------------------------------

	public static List<Auction> retrieveAllAuctions() throws ServiceException {
		try {
			HttpGet request = new HttpGet(SERVER_ADRESS + "FastSell/rest/auctions/");
			request.addHeader("accept", "application/json");

			HttpResponse response = executeHTTP(request);

			if (response.getStatusLine().getStatusCode() == 200) {
				String json = convertEntityToJSON(response);

				Genson g = new Genson();
				return g.deserialize(json, new GenericType<List<Auction>>() {});
			} else {
				throw new ServiceException("Error: No content recieved");
			}
		} catch (Exception e) {
			throw new ServiceException("Could not retrieve auctions", e);
		}
	}

	public static Auction getAuction(long auctionID) throws ServiceException {
		try {
			HttpResponse response = executeHTTP(new HttpGet(SERVER_ADRESS + "FastSell/rest/auctions/" + auctionID));

			if (response.getStatusLine().getStatusCode() == 200) {
				String json = convertEntityToJSON(response);

				Genson g = new Genson();
				return g.deserialize(json, Auction.class);
			} else {
				throw new ServiceException("Error: No content recieved");
			}
		} catch (Exception e) {
			throw new ServiceException("Could not retrieve auction", e);
		}
	}

	public static boolean checkUser(String username, String password) throws ServiceException {
		try {
			String uri = SERVER_ADRESS + "FastSell/rest/users/" + username + "/verify?password=" + password;

			HttpResponse response = executeHTTP(new HttpGet(uri));

			if (response.getStatusLine().getStatusCode() == 200) {
				return true;
			}
		} catch (Exception e) {
			throw new ServiceException("Error in checking user", e);
		}
		return false;
	}

	// ----------------------------------------------------------------------------------

	public static boolean placeBid(User user, Auction auction, double bid) {
		try {
			String uri = SERVER_ADRESS + "FastSell/rest/auctions/" + auction.getAuctionID() + "/placeBid?username="
					+ user.getName() + "&password=" + user.getPassword() + "&bidprice=" + bid;

			HttpResponse response = executeHTTP(new HttpPost(uri));

			if (response.getStatusLine().getStatusCode() == 200) {
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return false;
	}

	// ----------------------------------------------------------------------------------

	public static void createAuction(String title, String description, double startingPrice, int duration, User user) throws ServiceException {
		try {
			title = title.replace(" ", "%20");
			description = description.replace(" ", "%20");
			
			String uri = SERVER_ADRESS + "FastSell/rest/auctions/create?title=" + title + "&description="
					+ description + "&startingPrice=" + startingPrice + "&duration=" + duration + "&username="
					+ user.getName() + "&password=" + user.getPassword();
			
			HttpResponse response = executeHTTP(new HttpPost(uri)); 

			if (response.getStatusLine().getStatusCode() != 200) {
				throw new ServiceException("Could not create auction, check values");
			}
		} catch (Exception e) {
			throw new ServiceException("Could not create auction", e);
		}
	}

}
